local M = {}

-- LSP 提示配置
local config = {
  virtual_text = false, -- 行尾提示
  signs = {
    text = {
      [vim.diagnostic.severity.ERROR] = "",
      [vim.diagnostic.severity.WARN]  = "",
      [vim.diagnostic.severity.HINT]  = "",
      [vim.diagnostic.severity.INFO]  = "",
    },
    priority = 20, -- 提高图标优先级
  },
  update_in_insert = false,
  underline = true,
  severity_sort = true,
  float = {
    focusable = false,
    style = "minimal",
    border = "none",
    source = "always",
    header = "",
    prefix = "",
  },
}

vim.diagnostic.config(config)

-- 自动显示诊断信息
local function show_diagnostics()
  local line = vim.fn.line(".") - 1
  local bufnr = vim.api.nvim_get_current_buf()
  local diagnostics = vim.diagnostic.get(bufnr, { lnum = line })

  if #diagnostics > 0 then
    vim.diagnostic.open_float(nil, {
      focusable = true,
      close_events = { "BufLeave", "CursorMoved", "InsertEnter", "FocusLost" },
      border = 'none',
      source = 'always',
      prefix = '',
      scope = 'cursor',
    })
  end
end

-- 创建自动命令组
local diagnostic_group = vim.api.nvim_create_augroup("DiagnosticGroup", { clear = true })

-- 当光标移动时自动显示诊断信息
vim.api.nvim_create_autocmd("CursorHold", {
  group = diagnostic_group,
  pattern = "*",
  callback = show_diagnostics
})

-- 设置 CursorHold 的延迟时间（毫秒）
vim.opt.updatetime = 300

-- 悬浮窗口边框
vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, {
  border = "none",
})

vim.lsp.handlers["textDocument/signatureHelp"] = vim.lsp.with(vim.lsp.handlers.signature_help, {
  border = "none",
})

-- 设置按键映射
local on_attach = function(client, bufnr)
  local opts = { noremap = true, silent = true, buffer = bufnr }

  -- 自定义浮动窗口重命名函数
  local function rename()
    local curr_name = vim.fn.expand('<cword>')

    vim.ui.input({
      prompt = ' ',
      default = curr_name,
      kind = 'rename', -- 这会让 dressing.nvim 使用重命名专用的样式
    }, function(new_name)
      if new_name and new_name ~= curr_name then
        local params = vim.lsp.util.make_position_params()
        params.newName = new_name
        vim.lsp.buf.rename(new_name)
      end
    end)
  end

  local lspKeymap = {
    -- 跳转到定义
    { "n", "gd",         vim.lsp.buf.definition,          opts },
    -- 跳转到实现
    { "n", "gi",         vim.lsp.buf.implementation,      opts },
    -- 显示类型定义
    { "n", "gy",         vim.lsp.buf.type_definition,     opts },
    -- 重命名（使用浮动窗口）
    { "n", "<leader>w",  rename,                          opts },
    -- 显示代码操作
    { "n", "<leader>a",  vim.lsp.buf.code_action,         opts },
    -- 显示文档
    { "n", "K",          vim.lsp.buf.hover,               opts },
    -- 显示项目警告的功能
    { 'n', '<leader>ge', vim.diagnostic.setloclist,       opts },
    { 'n', 's;',         ":Telescope diagnostics<CR>",    opts },
    -- 查找上一个和下一个代码报错
    { "n", "[<space>",   vim.diagnostic.goto_prev,        opts },
    { "n", "]<space>",   vim.diagnostic.goto_next,        opts },
    -- lsp 显示引用
    { "n", 'gr',         ':Telescope lsp_references<CR>', opts },
    -- 代码格式化
    { { "n", "x" }, "<C-c>", function()
      vim.lsp.buf.format { async = true }
    end, opts },
  }

  for _key, value in pairs(lspKeymap) do
    vim.keymap.set(value[1], value[2], value[3]);
  end
end

-- 添加补全功能
-- local capabilities = vim.lsp.protocol.make_client_capabilities()
-- capabilities = require("cmp_nvim_lsp").default_capabilities(capabilities)

-- mason-lspconfig
require("mason").setup({
  ui = {
    icons = {
      package_installed = "✓",
      package_pending = "➜",
      package_uninstalled = "✗",
    },
  },
})

local mason_lspconfig = require("mason-lspconfig")
local lspconfig = require("lspconfig")

-- 自动设置 LSP
mason_lspconfig.setup({
  ensure_installed = {
    "vtsls",                 -- javascript typescript javascriptreact typescriptreact
    "cssls",                 -- css
    "emmet_language_server", -- emmet
    "html",                  -- html
    "lua_ls",                -- lua
    -- "volar",                 -- vue
    "pyright",               -- python
    -- "gopls",                 -- go
    "jdtls",                 -- java
    "clangd",                -- c c++
    "intelephense",          -- PHP
    "bashls",                -- Shell
  },
  automatic_installation = true
})

-- 自动设置 LSP
-- mason_lspconfig.setup({
--   function(server_name)
--     local opts = {
--       on_attach = on_attach,
--       capabilities = capabilities,
--     }
--
--     -- -- 特殊配置
--     if server_name == "lua_ls" then
--       opts.settings = {
--         Lua = {
--           diagnostics = {
--             globals = { "vim" },
--           },
--           workspace = {
--             library = vim.api.nvim_get_runtime_file("", true),
--             checkThirdParty = false,
--           },
--           telemetry = {
--             enable = false,
--           },
--           semantic = {
--             enable = false, -- 禁用语义标记以避免索引错误
--           },
--         },
--       }
--     end
--
--     -- Emmet LSP 配置
--     if server_name == "emmet_language_server" then
--       opts.filetypes = {
--         "html", "typescriptreact", "javascriptreact", "css", "sass", "scss", "less",
--         "php", -- 添加 PHP 支持
--       }
--     end
--
--     -- intelephense PHP LSP 配置
--     if server_name == "intelephense" then
--       opts.root_dir = function(fname)
--         return require("lspconfig").util.root_pattern(
--           "composer.json",
--           "composer.lock",
--           "vendor",
--           ".git"
--         )(fname) or vim.fn.getcwd()
--       end
--       opts.settings = {
--         intelephense = {
--           files = {
--             maxSize = 1000000,
--           },
--         }
--       }
--       -- 禁用特定文件类型的某些功能
--       opts.on_attach = function(client, bufnr)
--         -- 调用原有的 on_attach
--         on_attach(client, bufnr)
--
--         -- 禁用特定补全来源
--         local ok, cmp = pcall(require, 'cmp')
--         if ok then
--           -- 获取当前的 sources 配置
--           local current_sources = cmp.get_config().sources
--
--           -- 修改 nvim_lsp source 的配置，保留其他 sources
--           for _, source in ipairs(current_sources) do
--             if source.name == 'nvim_lsp' then
--               source.entry_filter = function(entry, ctx)
--                 -- 过滤掉 HTML 结束标签的补全
--                 if entry.completion_item.label:match('^</') then
--                   return false
--                 end
--                 return true
--               end
--             end
--           end
--
--           -- 使用修改后的配置
--           cmp.setup.buffer({
--             sources = current_sources
--           })
--         end
--       end
--     end
--     -- vue3 volar 配置
--     if server_name == "volar" then
--       opts.settings = {
--         semantic = {
--           enable = true,
--         }
--       }
--       opts.filetypes = { 'vue' }
--       opts.init_options = {
--         vue = {
--           hybridMode = false -- 禁用混合模式
--         }
--       }
--     end
--     lspconfig[server_name].setup(opts)
--   end,
-- })

-- vim 折叠代码
require('ufo').setup()

-- {javascriptreact, typescriptreact, PHP} filetype BufWritePre format
vim.api.nvim_create_autocmd("BufWritePre", {
  pattern = { "*.jsx", "*.tsx" },
  callback = function()
    vim.lsp.buf.format { async = true }
  end,
})

-- { php } FileType indent
vim.api.nvim_create_autocmd("FileType", {
  pattern = { "php" },
  callback = function()
    vim.opt_local.smartindent = false -- 禁用智能缩进
    vim.opt_local.autoindent = true   -- 保持基本的自动缩进
    -- 只保留 HTML 标签相关的缩进键
    vim.opt_local.indentkeys = ""
    -- 设置新行时的行为
    vim.opt_local.formatoptions:remove('o') -- 不要在使用 o/O 时自动添加注释前缀
    vim.opt_local.formatoptions:remove('r') -- 不要在按回车时自动添加注释前缀
  end,
})

return M
